package com.huaguoguo.cyg.vcs.manager.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.IoUtil;
import cn.hutool.core.util.CharsetUtil;
import cn.hutool.core.util.StrUtil;
import com.huaguoguo.cyg.entity.po.SVNCommintLog;
import com.huaguoguo.cyg.vcs.manager.VersionControlManager;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.Assert;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

@Slf4j
@Data
public class SVNManager extends VersionControlManager {
    /**
     * 分隔符
     */
    public final static String splitStr = "------------------------------------------------------------------------";


    @Override
    public void execLogCmd() throws IOException {
        // 执行svn update命令
        String svnUpdateCmd = "svn update {}";
        String cmd = StrUtil.format(svnUpdateCmd,moduleRootPath);
        log.info("执行命令：{}",cmd);
        Process exec = Runtime.getRuntime().exec(cmd);
        log.info("执行结果：{}", IoUtil.read(exec.getInputStream(), CharsetUtil.systemCharset()));
        // 执行 svn log命令
        String svnLogCmd = "svn log {} --search {} -v -l 100";
        cmd = StrUtil.format(svnLogCmd, moduleRootPath, commiterName);
        log.info("执行命令：{}",cmd);
        exec = Runtime.getRuntime().exec(cmd);
        // 写入文件中
        FileUtil.writeFromStream(exec.getInputStream(),logPath);
    }

    /**
     * 解析svn提交日志得到分组的提交信息列表
     * @return
     */
    @Override
    public List<List<String>> parseSVNLogFile(){
        List<String> lines = FileUtil.readLines(logPath, "GBK");
        // 找出分隔符的位置
        List<Integer> splitIndexList = new ArrayList<>();
        for (int i = 0; i < lines.size(); i++) {
            if (splitStr.equals(lines.get(i))) {
                splitIndexList.add(i);
            }
        }
        // 按分隔符拆分成一组信息的列表
        List<List<String>> oneInfoList = new ArrayList<>();
        for (int i = 0; i < splitIndexList.size()-1; i++) {
            List<String> oneInfo = new ArrayList<>();
            Integer startIndex = splitIndexList.get(i);
            Integer endIndex = splitIndexList.get(i + 1);
            for (int j = startIndex+1; j < endIndex; j++) {
                oneInfo.add(lines.get(j));
            }
            oneInfoList.add(oneInfo);
        }
        return oneInfoList;
    }

    /**
     * 解析出提交记录结构化对象
     * @param oneInfoList
     * @return
     */
    @Override
    public List<SVNCommintLog> getSVNCommintLogList(List<List<String>> oneInfoList){
        Assert.isTrue(CollUtil.isNotEmpty(oneInfoList), "待解析列表不能为空！");
        return oneInfoList.stream()
                .map(oneInfo -> {
                    List<String> changePaths = oneInfo.stream()
                            .filter(StrUtil::isNotEmpty)
                            .filter(s -> s.startsWith(" "))
                            // 去掉非本项目的提交文件
                            .filter(s -> {
                                String svnPath = s.toUpperCase();
                                // 先找到src的位置，需要按src位置截取路径备用
                                int srcIndex = s.indexOf("src");
                                // 如果路径中没有src，说明是项目根目录文件，可以直接判断是否属于本项目
                                if (srcIndex > 0) {
                                    svnPath = s.substring(0, srcIndex);
                                }
                                return svnPath.contains(properties.getProperty("app.name").toUpperCase());
                            }).collect(Collectors.toList());
                    return SVNCommintLog.builder().commintInfo(oneInfo.get(0))
                            .commintMessage(CollUtil.getLast(oneInfo))
                            .changePaths(changePaths).build();
                }).collect(Collectors.toList());
    }

    /**
     * 复制和移动提交文件到指定目录
     * @param svnCommintLogList
     */
    @Override
    public void copyAndMoveCommitFile(List<SVNCommintLog> svnCommintLogList){
        // 取文件，生成一个文件夹，以 commintMessage 命名
        // 导入导出的classes路径
        String classesPath = new StringBuilder(moduleBuildPath).append(properties.getProperty("app.name"))
                .append("\\WEB-INF\\classes\\").toString();
        // web根目录
        String webRootPath = new StringBuilder(moduleBuildPath).append(properties.getProperty("app.name"))
                .append("\\").toString();
        svnCommintLogList.forEach(svnCommintLog -> {
            // 本次提交文件的web根目录
            String expWebRootPath = new StringBuilder(expPath)
                    // r1434064 | liujianhua | 2020-03-18 15:05:19 +0800 (周三, 18 3月 2020) 取第一个 r1434064
                    .append(svnCommintLog.getCommintInfo().split("\\|")[0].trim())
                    .append("-").append(svnCommintLog.getCommintMessage())
                    .append("\\").append(properties.getProperty("app.name"))
                    .append("\\").toString();
            svnCommintLog.getChangePaths().stream()
                    .map(String::trim)
                    .map(s -> {
                        // 防止文件路径后携带其他信息,去掉后面的字符串
                        // 例如： A /Cust/.../hello.java (from hello1.java)
                        if (s.indexOf(" ", 2) == -1) {
                            return s;
                        }
                        return s.substring(0, s.indexOf(" ", 2));
                    }).forEach(s -> {
                // 去build文件夹中拿文件
                // 如果提交的是java代码，去classesPath里找
                String srcPath = null;
                String destPath = null;
                if (s.contains("src/java")) {
                    // class文件的路径
                    String classPath = s.substring(s.indexOf("src/java"))
                            .replace("src/java/", "")
                            .replace(".java", ".class");
                    srcPath = classesPath + classPath;
                    destPath = expWebRootPath + "WEB-INF\\classes\\" + classPath;
                } else if (s.contains("src/resource")) {
                    String resourcePath = s.substring(s.indexOf("WEB-INF")).replace("WEB-INF/classes/", "");
                    srcPath = classesPath + resourcePath;
                    destPath = expWebRootPath + resourcePath;
                } else if (s.contains("src/web")) {
                    String webPath = s.substring(s.indexOf("src/web")).replace("src/web/", "");
                    srcPath = webRootPath + webPath;
                    destPath = expWebRootPath + webPath;
                } else if (!s.contains("/src/")) {
                    return;
                }
                // 目录不做处理
                if (FileUtil.isDirectory(srcPath) || FileUtil.isDirectory(destPath)) {
                    return;
                }
                FileUtil.copy(srcPath, destPath, true);
            });
            log.info("【{}】{}",svnCommintLog.getCommintMessage(),"导出完成");
        });
    }

}